package com.fs.controller.v2;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.controller.vo.customer.*;
import com.fs.global.config.CustomConfig;

import static com.fs.utils.HttpUtils.HttpResult;

import com.fs.global.init.RoleName;
import com.fs.service.CustomerService;
import com.fs.utils.HttpUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.binary.Base64;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.lang.Nullable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.nio.charset.StandardCharsets;
import java.security.spec.AlgorithmParameterSpec;

@Api(value = "微信小程序相关", tags = "客户", description = "小程序用户使用")
@RestController
@RequestMapping("/v2/customer")
@RequiresRoles(value = {RoleName.GUEST, RoleName.CUSTOMER}, logical = Logical.OR)
@Validated
public class CustomerController {

    private final static String OPENID_QUERY_URL_Format =
            "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

    private final CustomConfig config;


    public CustomerController(CustomConfig config) {
        this.config = config;
    }

    @ApiOperation("获取openID")
    @GetMapping("/openId")
    public RespGetOpenID getOpenID(@NotBlank @RequestParam String jsCode) throws Exception {
        String url = String.format(OPENID_QUERY_URL_Format, config.getWxAppID(), config.getWxAppSecret(), jsCode);
        HttpResult httpResult = HttpUtils.get(url);
        if (httpResult.getStatusCode() != 200) {
            throw new Exception("微信请求openid失败");
        }

        JSONObject jsonObject = JSON.parseObject(httpResult.getResult());
        Object errcode = jsonObject.get("errcode");
        if (errcode != null) {
            int errCode = Integer.parseInt(String.valueOf(errcode));
            if (errCode != 0) {
                String errMsg = jsonObject.get("errmsg").toString();
                throw new Exception("微信登录异常:" + errMsg);
            }
        }

        String openid = jsonObject.get("openid").toString();
        String sessionKey=jsonObject.get("session_key").toString();
        return new RespGetOpenID().setOpenID(openid).setSessionKey(sessionKey);
    }

    @ApiOperation("获取手机号")
    @GetMapping("/phone")
    public RespGetPhone getPhone(@Valid ReqGetPhone req) throws Exception {
        String str = decrypt(req.getEncryptData(), req.getSessionKey(), req.getIv());
        JSONObject jsonObject = JSON.parseObject(str);
        if (jsonObject == null) {
            throw new Exception("解码手机号失败");
        }

        Object phone = jsonObject.get("purePhoneNumber");
        if (phone == null) {
            throw new Exception("获取手机号失败");
        }
        return new RespGetPhone(phone.toString());
    }

    @Nullable
    private String decrypt(String data, String key, String iv) {
        //被加密的数据
        byte[] dataByte = Base64.decodeBase64(data);
        //加密秘钥
        byte[] keyByte = Base64.decodeBase64(key);
        //偏移量
        byte[] ivByte = Base64.decodeBase64(iv);
        try {
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivByte);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            return new String(cipher.doFinal(dataByte), StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
